<?php
/**
 * Created by 老吴.
 * UserMsg:砥砺前行，扬帆起航
 * email:cwwx0128@qq.com
 * QQ:1113249273
 * QQ群:925283872
 * 微信:cww0128
 * Date: 2021/4/15
 * Time: 23:08
 */

namespace app\api\controller;

use app\common\controller\Api;
use app\common\model\ChargeCouponReceivelog;
use think\Db;
use think\Exception;
use think\Loader;
use think\Log;
use function GuzzleHttp\Psr7\try_fopen;

class AliMinappLogin extends Api
{
    protected $noNeedLogin = ['login','getUserInfoAli'];
    protected $noNeedRight = ['*'];
    protected $appId;
    protected $gatewayUrl;
    protected $rsaPrivateKey;
    protected $alipayrsaPublicKey;
    private static $apiSecret = 'vBe1EOMLr2VoP18Fhp0kpA==';

    private $certArr=[];


    public function __construct()
    {
        $this->appId = '2021004184604463';//appID
        $this->gatewayUrl = 'https://openapi.alipay.com/gateway.do';//支付宝网关地址
        $this->rsaPrivateKey = 'MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCjgU9CNN+boSDhyV22OPdt4dSJjvXeAQWBd2co4T8q4iwKVNatimWIgZGiLLIYXM/RVS/TDrsSF/xCOo3aLjocJhJrEGfs97HrrflpFqOo9H6ITCi72rw5J6WuP5vn+8Q0maUspKmni9Lr/x9HryLr9CEMAa/a3QwY43oNa4zjYE8a0PcmE5BtbWfdIZiCR7nBVPpfZRQ7mKNC5GmesU9c3LBTShupcXiUxgNw6VLlHJNqK0fOWhLVHOC3zWFJNenNaNIsmTCh9spPdaglAftKhIlgT3Rbb7fFl3B3HHLi5SiYxMef3SKocxz5LmlLsHjXdX45oV2BUoD7wcWCrItlAgMBAAECggEBAJEeOPGDKh/gL+YWKkWMZBczw8bfitsivvc8ueOvn7f5C6uTxwI5/oncrhxpXRyAa7bYy9ygi2qwvSUvAS3vr4XCSMCbzBGnelO6ks4x2MohTpi8N78bkcmMpeF09XQ9odQptk9cSnO5h1gMlH+0MuOHRzl32dQAMzd31qFInsBDEUi/pOa+GByItNVFIORvvRZhCG9vSTiXMk5IKWXFkQFRVkgeMNXN+jTCKpU69mMam+XtwD9pL26OwpQA+vvrtV6xDbPyGK2Ye9oZ7Sdh70sPxkMbQA7y7/g9iRSBGpzdvCz0CmqpGtUOsVeZNV7Nhsi1UIRmpxPcviuVYDeg3hUCgYEA6TVLdjIqJvIJLnWki8WvRYH7BRMh2YHNdshzQ9ciF4QBklXg1sgtG6vwUuOXnqcB05MgAawf0douvcJDRuu/W2Wwyv1YkXJ1mSk5IAFRhDsuttymwwBEDQ0CNKKc3J6NZqT61m/5sEnaaiVmZ/SO4mq1n5U4sJp7S0d6MWKwSysCgYEAs3wXzGvnaQEAZFm58WT6yTlKX+iZt6OPzrb20eB5bv+AK3SPiFliHU0gNluJIitKKsNMOZS76DpzZKI6apWylPYIGa639Jl3H+l4nWHb8fcy/qz4U3GzLqFxq9ai8xCSJak7nxgiITdu2LX5dfTxUWNGAG0tsIEEYfuCZERi+68CgYB7l08CuNs2AJd1E8u8d2vH/na13cnWp7/n75uGnIDozYC3uOOLcFLXk2utwggcgI2rPxF7UWkbofGbh1R4RYAIRABJ07IYgvxnyz0HBSvaVDMRniaSuZVXBUnh8zwGf9CYUV7OPlGpZ7pk/qUi+qyuuba/eCmvDm/BGYRcn9ymOQKBgElpuno8sHx8kmJ5aNrZyNJBgrBT/XvlhM6ye6ZAwKqsCwq7NHI6zSza/Q/+xMqbFk0DcMwkj+9e6RACYw5xiIfxUkLe+hMsKlN9NX56JnKD//G3YiMPYJD0LABzXFc7MewBmodqYZtghxBQ7mZW99WoW1uVTJjjTJ2fOCg26J21AoGAIWfKokbyDW1/lU/yThSdUkfm6tDxhVz96M7xkQPVZqnmAnFAbTpQn5KhsdJsTIOjKaEeUuvAtYl25dBRTOPkQO2AVfHoAqLm+B+Q4H+H1EkH3UenlHwmuv+z7dUYA7NwLiUS9CQiNFphcFCzDytOklmp+IPlNezDaAXd00VqgFs=';//应用私钥

        $this->alipayrsaPublicKey = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo4FPQjTfm6Eg4cldtjj3beHUiY713gEFgXdnKOE/KuIsClTWrYpliIGRoiyyGFzP0VUv0w67Ehf8QjqN2i46HCYSaxBn7Pex6635aRajqPR+iEwou9q8OSelrj+b5/vENJmlLKSpp4vS6/8fR68i6/QhDAGv2t0MGON6DWuM42BPGtD3JhOQbW1n3SGYgke5wVT6X2UUO5ijQuRpnrFPXNywU0obqXF4lMYDcOlS5RyTaitHzloS1Rzgt81hSTXpzWjSLJkwofbKT3WoJQH7SoSJYE90W2+3xZdwdxxy4uUomMTHn90iqHMc+S5pS7B413V+OaFdgVKA+8HFgqyLZQIDAQAB';//支付宝公钥
        parent::__construct();
        //支付宝证书路径
        $this->certArr=[
            'appCertPath' => ROOT_PATH."addons/epay/certs/appCertPublicKey.crt",//应用公钥证书
            'alipayCertPath' => ROOT_PATH."addons/epay/certs/alipayCertPublicKey.crt",//支付宝公钥证书
            'rootCertPath' => ROOT_PATH."addons/epay/certs/alipayRootCert.crt",//根证书
        ];
    }

    /**
     * 用户登录
     */
    public function login()
    {

        Loader::import('aliapo.AopClientSelf', APP_PATH . '../addons/alilogin/extend/');
        Loader::import('aliapo.AopCertClient', APP_PATH . '../addons/alilogin/extend/');
        Loader::import('aliapo.request.AlipaySystemOauthTokenRequestSelf', APP_PATH . '../addons/alilogin/extend/');
        Loader::import('aliapo.request.AlipayUserUserinfoShareRequest', APP_PATH . '../addons/alilogin/extend/');

        $type = 'cert';
        $accessToken='';
        $param = $this->request->param();
        if ($type == 'common') {
            //非整数模式
            $aop = new \AopClientSelf();
            $aop->gatewayUrl = $this->gatewayUrl;
            $aop->appId = $this->appId;
            $aop->rsaPrivateKey = $this->rsaPrivateKey;
            $aop->alipayrsaPublicKey = $this->alipayrsaPublicKey;
            $aop->apiVersion = '1.0';
            $aop->signType = 'RSA2';
            $aop->postCharset = 'utf-8';
            $aop->format = 'json';
            $aop->charset = 'UTF-8';

            $request = new \AlipaySystemOauthTokenRequestSelf();
            $request->setGrantType("authorization_code");
            $request->setCode($param['code']);
            $result = $aop->execute($request);
            if (isset($result->error_response)) {
                $this->error($result->error_response->sub_msg);
            }
            $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
            $accessToken = $result->$responseNode->access_token;
        }
        else{
            //证书模式
            $c = new \AopCertClient();
            $appCertPath = $this->certArr['appCertPath'];
            $alipayCertPath =$this->certArr['alipayCertPath'];
            $rootCertPath =$this->certArr['rootCertPath'];
            $c->gatewayUrl = "https://openapi.alipay.com/gateway.do";
            $c->appId = $this->appId;//1
            $c->rsaPrivateKey = $this->rsaPrivateKey;//1
            $c->format = "json";
            $c->charset = "UTF-8";
            $c->signType = "RSA2";
            //调用getPublicKey从支付宝公钥证书中提取公钥
            $c->alipayrsaPublicKey = $c->getPublicKey($alipayCertPath);//1
            //是否校验自动下载的支付宝公钥证书，如果开启校验要保证支付宝根证书在有效期内
            $c->isCheckAlipayPublicCert = true;
            //调用getCertSN获取证书序列号
            $c->appCertSN = $c->getCertSN($appCertPath);
            //调用getRootCertSN获取支付宝根证书序列号
            $c->alipayRootCertSN = $c->getRootCertSN($rootCertPath);
            //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.user.userinfo.share
            //$request = new \AlipayUserUserinfoShareRequest();
            //$request->setProdCode($param['code']);

            $request = new \AlipaySystemOauthTokenRequestSelf();
            $request->setGrantType("authorization_code");
            $request->setCode($param['code']);
            //授权类接口执行API调用时需要带上accessToken
            $response = $c->execute($request, "accessToken");
            $response=json_decode( json_encode( $response),true);
            print_r($response);
            if(isset($response['alipay_system_oauth_token_response'])){
                $accessToken=$response['alipay_system_oauth_token_response']['access_token'];
            }else{
//                \think\Log::error($response);
                $this->error('授权失败001');
            }
        }
        $ret = self::getUserInfoAli($accessToken);
        print_r($ret);
        if ($ret->alipay_user_info_share_response->code == '10000') {
            $userinfo = \app\admin\model\User::where(['alipay_id' => $ret->alipay_user_info_share_response->user_id])->find();
            if ($userinfo) {
                $userinfo->alipay_nickname = $ret->alipay_user_info_share_response->nick_name;
                $userinfo->alipay_avatar = $ret->alipay_user_info_share_response->avatar;
                //$userinfo->gender = $ret->alipay_user_info_share_response->gender == 'm' ? '1' : '0';
                //$userinfo->city = $ret->alipay_user_info_share_response->city;
                //$userinfo->province = $ret->alipay_user_info_share_response->province;
                //$userinfo->country = '中国';
                $userinfo->save();
                $this->auth->direct($userinfo['id']);
            } else {
                $user = new \app\admin\model\User();
                $pid = 0;
                if (isset($param['inviteCode']) && !empty($param['inviteCode'])) {
                    $pid = \app\admin\model\User::where('invite_code', $param['inviteCode'])->value('id');
                    $pid = $pid > 0 ? $pid : 0;
                    //加优惠券


                    /*if($pid){
                        $coupon = Db::name('charge_coupon')->where('type','0')->where('deletetime',null)->find();
                        $nowtime = time();
                        $data = array(
                            'user_id' => $pid,
                            'charge_coupon_id' => 1,
                            'get_type' => 0,
                            'use_time' => $coupon['use_time'],
                            'coupon_type' => 0,
                            'time_start' => $nowtime,
                            'time_end' => ($coupon['save_time']*24*60*60)+$nowtime,
                            'status' => 0,
                            'get_coupon_time' => $nowtime,
                            'createtime' => $nowtime,
                        );
                        Db::name('charge_coupon_receivelog')->insert($data);
                    }*/


                }

                if (isset($ret->alipay_user_info_share_response->avatar)) {
                    $alipay_avatar = $ret->alipay_user_info_share_response->avatar;
                } else {
                    $alipay_avatar = '';
                }

                if(isset($ret->alipay_user_info_share_response->nick_name)){
                    $alipay_nickname = $ret->alipay_user_info_share_response->nick_name;
                }else{
                    $alipay_nickname='';
                }

                $user->data([
                    'alipay_nickname' => $ret->alipay_user_info_share_response->nick_name,
                    'alipay_avatar' => $ret->alipay_user_info_share_response->avatar,
                    //'gender' => $ret->alipay_user_info_share_response->gender == 'm' ? '1' : '0',
                    //'city' => $ret->alipay_user_info_share_response->city,
                    //'province' => $ret->alipay_user_info_share_response->province,
                    //'country' => '中国',
                    'status' => 'normal',
                    'alipay_id' => $ret->alipay_user_info_share_response->user_id,
                    'invite_code' => \app\common\model\User::createInviteCode(),
                    'pid' => $pid
                ]);
                $user->save();
                $this->auth->direct($user->id);
            }
            $this->success('登录成功', ['token' => $this->auth->getToken()]);
        } else {


            \think\Log::error($ret);
            $this->error($ret->alipay_user_info_share_response->msg . '错误码：' . $ret->alipay_user_info_share_response->code);
        }

    }


    /**
     * 获取支付宝用户信息
     * @param $accessToken
     */
    protected function getUserInfoAli($accessToken)
    {
        Loader::import('aliapo.AopClientSelf', APP_PATH . '../addons/alilogin/extend/');
        Loader::import('aliapo.request.AlipayUserInfoShareRequestSelf', APP_PATH . '../addons/alilogin/extend/');
        $type=3;
        if($type=='common'){
            //非证书模式
            $aop = new \AopClientSelf ();
            $aop->gatewayUrl = $this->gatewayUrl;
            $aop->appId = $this->appId;
            $aop->rsaPrivateKey = $this->rsaPrivateKey;
            $aop->alipayrsaPublicKey = $this->alipayrsaPublicKey;
            $aop->apiVersion = '1.0';
            $aop->signType = 'RSA2';
            $aop->postCharset = 'utf-8';
            $aop->format = 'json';
            $request = new \AlipayUserInfoShareRequestSelf ();
            $result = $aop->execute($request, $accessToken);
            return $result;
        }else{
            //证书模式
            $c = new \AopCertClient();
            $appCertPath = $this->certArr['appCertPath'];
            $alipayCertPath =$this->certArr['alipayCertPath'];
            $rootCertPath =$this->certArr['rootCertPath'];
            $c->gatewayUrl = "https://openapi.alipay.com/gateway.do";
            $c->appId = $this->appId;
            $c->rsaPrivateKey = $this->rsaPrivateKey;
            $c->format = "json";
            $c->charset = "UTF-8";
            $c->signType = "RSA2";
            //调用getPublicKey从支付宝公钥证书中提取公钥
            $c->alipayrsaPublicKey = $c->getPublicKey($alipayCertPath);
            //是否校验自动下载的支付宝公钥证书，如果开启校验要保证支付宝根证书在有效期内
            $c->isCheckAlipayPublicCert = true;
            //调用getCertSN获取证书序列号
            $c->appCertSN = $c->getCertSN($appCertPath);
            //调用getRootCertSN获取支付宝根证书序列号
            $c->alipayRootCertSN = $c->getRootCertSN($rootCertPath);
            $request = new \AlipayUserInfoShareRequestSelf ();
            $result = $c->execute($request, $accessToken);
            return $result;
        }
    }

    /**
     * 支付宝小程序绑定手机号
     * @throws Exception
     * @throws \think\exception\DbException
     */
    public function bindAlipayMobile()
    {
        trace('深蓝7');
        trace($this->auth->id);

        $currentUserInfo = \app\common\model\User::get(['id' => $this->auth->id]);
        trace('深蓝8');
        trace($currentUserInfo);
        if (!empty($currentUserInfo->mobile)) {
            $this->error('您已绑定了手机号了');
        }
        $params = $this->request->param();
        trace('深蓝9');
        trace($params);
        $encryptedData = $params['response'];
        $result = self::decryptData($encryptedData, self::$apiSecret);
        $result = json_decode($result, true);
        trace('深蓝10');
        trace($result);
        if ($result['code'] == 10000) {
            $mobile = $result['mobile'];
            //当微信绑定了该手机号则把支付宝信息绑定该账号
            $userInfo = \app\common\model\User::get(['mobile' => $mobile]);
            trace('深蓝11');
            trace($userInfo);
            if ($userInfo) {
                Db::startTrans();
                try {
                    $userInfo->alipay_avatar = $currentUserInfo->alipay_avatar;
                    $userInfo->alipay_nickname = $currentUserInfo->alipay_nickname;
                    $userInfo->alipay_id = $currentUserInfo->alipay_id;
                    $userInfo->save();
                    $currentUserInfo->delete();
                    $this->auth->direct($userInfo->id);
                    Db::commit();
                } catch (Exception $e) {
                    Db::rollback();
                    $this->error("绑定手机号失败1：" . $e->getMessage());
                } catch (\Exception $e) {
                    Db::rollback();
                    $this->error("绑定手机号失败2：" . $e->getMessage());
                }
                $this->success('绑定手机号成功', ['token' => $this->auth->getToken()], 3);
            } else {
                //发放体验券
                Db::startTrans();
                try {
                    $currentUserInfo->mobile = $mobile;
                    $currentUserInfo->save();
                    //新用户登录获取优惠券
                    ChargeCouponReceivelog::grantCoupon($this->auth->id);
                    if ($currentUserInfo->pid > 0) {
                        ChargeCouponReceivelog::grantCoupontg($currentUserInfo->pid);
                    }
                    Db::commit();
                } catch (Exception $e) {
                    Db::rollback();
                    $this->error("绑定手机号失败3：" . $e->getTraceAsString());
                } catch (\Exception $e) {
                    Db::rollback();
                    $this->error("绑定手机号失败4：" . $e->getMessage());
                }
                $this->success('绑定手机号成功');
            }
        }
        $this->error($result['subMsg']);
    }

    /**
     * 解密数据
     * @param $encrypted_data
     * @param string $key
     * @return false|string
     */
    private static function decryptData($encrypted_data, $key = '')
    {
        $aesKey = base64_decode($key);
        $iv = 0;
        $aesIV = base64_decode($iv);
        $aesCipher = base64_decode($encrypted_data);
        $result = openssl_decrypt($aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);
        return $result;
    }
}